package com.wsc.wsckeeper.activities;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import android.annotation.SuppressLint;
import android.app.DatePickerDialog;
import android.database.SQLException;
import android.os.Bundle;
import android.text.Editable;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.Spinner;

import com.wsc.wsckeeper.R;
import com.wsc.wsckeeper.activities.base.BaseActivity;
import com.wsc.wsckeeper.adapter.CardsTypeAdapter;
import com.wsc.wsckeeper.adapter.CurrencyAdapter;
import com.wsc.wsckeeper.components.CardNumberEditText;
import com.wsc.wsckeeper.components.ExDatePickerDialog;
import com.wsc.wsckeeper.enums.Mode;
import com.wsc.wsckeeper.listeners.OnItemSelectedListenerImpl;
import com.wsc.wsckeeper.listeners.TextWatcherImpl;
import com.wsc.wsckeeper.managers.ResourceManager;
import com.wsc.wsckeeper.model.KModel;
import com.wsc.wsckeeper.model.KRuntimeModel;
import com.wsc.wsckeeper.model.entity.CardE;
import com.wsc.wsckeeper.model.entity.CardTypeE;
import com.wsc.wsckeeper.model.entity.CurrencyE;
import com.wsc.wsckeeper.persistence.dao.CardDAO;
import com.wsc.wsckeeper.persistence.dao.CardTypeDAO;
import com.wsc.wsckeeper.persistence.dao.CurrencyDAO;
import com.wsc.wsckeeper.utils.CollectionUtils;
import com.wsc.wsckeeper.utils.DateUtils;

@SuppressLint("SimpleDateFormat")
public class CardActivity extends BaseActivity {

	private CardNumberEditText cnCardNumber;
	private EditText etCardCode;
	private EditText etCardExpiresEnd;
	private EditText etCardSing;
	private EditText etCardOwner;
	private EditText etCardDescription;
	private ImageButton ibCardExpiresEndEdit;
	private Spinner spCardType;
	private Spinner spCardCurrency;
	private Button btAction;

	private List<EditText> components = new ArrayList<EditText>();
	private Date cardExpiresEndDate;

	private CardE card;
	private List<CardTypeE> cardsType;
	private List<CurrencyE> currencies;

	private SimpleDateFormat sdf;
	private boolean isFisrtTypeCall = true;
	private boolean isFisrtCurrencyCall = true;

	public void onCreate(Bundle savedInstanceState) {
		setContentView(R.layout.activity_card);
		super.onCreate(savedInstanceState);
	}

	@Override
	public void initComponents() {
		cnCardNumber = (CardNumberEditText) findViewById(R.id.card_number);
		etCardCode = (EditText) findViewById(R.id.card_code);
		etCardExpiresEnd = (EditText) findViewById(R.id.card_expires_end);
		etCardOwner = (EditText) findViewById(R.id.card_owner);
		etCardSing = (EditText) findViewById(R.id.card_sign);
		etCardDescription = (EditText) findViewById(R.id.card_description);
		ibCardExpiresEndEdit = (ImageButton) findViewById(R.id.card_expires_end_edit);
		spCardType = (Spinner) findViewById(R.id.card_type);
		spCardCurrency = (Spinner) findViewById(R.id.card_currency);
		btAction = (Button) findViewById(R.id.action);
	}

	@Override
	public void initValues() {
		components.add(cnCardNumber);
		components.add(etCardCode);
		components.add(etCardSing);
		components.add(etCardOwner);
		components.add(etCardDescription);

		mode = KModel.getInstance().getCardMode();
		card = KModel.getInstance().getCard();

		sdf = new SimpleDateFormat(ResourceManager.getStringValue(R.string.format_card));

		try {
			cardsType = runtime.getCardsType();
			currencies = runtime.getCurrensy();
			if (cardsType == null) {
				cardsType = CardTypeDAO.queryForAll();
				runtime.setCardsType(cardsType);
			}
			if (currencies == null) {
				currencies = CurrencyDAO.queryForAll();
				runtime.setCurrensy(currencies);
			}
		} catch (SQLException e) {
			showExceptionAsDialog(e);
		} catch (Exception e) {
			showExceptionAsDialog(e);
		}

		if (card != null) {
			cnCardNumber.setText(card.getNumber());
			etCardCode.setText(String.valueOf(card.getCode()));
			etCardOwner.setText(card.getOwner());
			etCardSing.setText(String.valueOf(card.getSing()));
			etCardDescription.setText(card.getDescription());
			etCardExpiresEnd.setText(sdf.format(card.getExpiresEnd()));
			cardExpiresEndDate = card.getExpiresEnd();
		}

		if (cardsType != null && cardsType.size() > 0) {
			spCardType.setAdapter(new CardsTypeAdapter(this, cardsType));
			if (card != null && card.getCardType() != null)
				spCardType.setSelection(CollectionUtils.getItemIndex(cardsType, card.getCardType()));
		}

		if (currencies != null && currencies.size() > 0) {
			spCardCurrency.setAdapter(new CurrencyAdapter(this, currencies));
			if (card != null && card.getCurrency() != null)
				spCardCurrency.setSelection(CollectionUtils.getItemIndex(currencies, card.getCurrency()));
		}

		if (isMode(Mode.SHOW)) {
			editMode(false);
		} else {
			if (isMode(Mode.ADD)) {
				btAction.setText(R.string.action_add);
				getActionBar().setSubtitle(ResourceManager.getStringValue(R.string.action_add_card));
			} else {
				if (isMode(Mode.EDIT)) {
					btAction.setText(R.string.action_save);
					getActionBar().setSubtitle(ResourceManager.getStringValue(R.string.action_edit_card));
				}
			}
		}

		btAction.setEnabled(false);
	}

	@Override
	public void initListeners() {
		for (int i = 0; i < components.size(); i++) {
			final EditText edit = components.get(i);
			edit.addTextChangedListener(new TextWatcherImpl() {
				
				@Override
				public void afterTextChanged(Editable s) {
					btAction.setEnabled(true);
					edit.setError(null);
				}
				
			});
		}

		ibCardExpiresEndEdit.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				Calendar date = GregorianCalendar.getInstance();
				int year = date.get(Calendar.YEAR);
				int monthOfYear = date.get(Calendar.MONTH);
				int dayOfMonth = date.get(Calendar.DATE);

				if (card != null && card.getExpiresEnd() != null) {
					year = DateUtils.getYearFromDate(card.getExpiresEnd());
					monthOfYear = DateUtils.getMonthFromDate(card.getExpiresEnd());
					dayOfMonth = DateUtils.getDateFromDate(card.getExpiresEnd());
				}

				new ExDatePickerDialog(CardActivity.this, new DatePickerDialog.OnDateSetListener() {

					@Override
					public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
						cardExpiresEndDate = DateUtils.getDate(year, monthOfYear);
						etCardExpiresEnd.setText(sdf.format(cardExpiresEndDate));
						btAction.setEnabled(true);
					}
				}, year, monthOfYear, dayOfMonth).show();
			}
		});

		spCardType.setOnItemSelectedListener(new OnItemSelectedListenerImpl() {

			@Override
			public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
				if (isFisrtTypeCall) {
					isFisrtTypeCall = false;
					return;
				}

				btAction.setEnabled(true);
			}
		});

		spCardCurrency.setOnItemSelectedListener(new OnItemSelectedListenerImpl() {

			@Override
			public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
				if (isFisrtCurrencyCall) {
					isFisrtCurrencyCall = false;
					return;
				}

				btAction.setEnabled(true);
			}
		});

		btAction.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				try {
					if (isValidFields() == false)
						return;

					if (card == null) {
						card = new CardE();
						card.setCreated(Calendar.getInstance().getTime());
					}

					card.setNumber(cnCardNumber.getText().toString().replaceAll(" ", ""));
					card.setCode(etCardCode.getText().toString());
					card.setExpiresEnd(cardExpiresEndDate);
					card.setSing(etCardSing.getText().toString());
					card.setOwner(etCardOwner.getText().toString());
					card.setDescription(etCardDescription.getText().toString());
					card.setCardType(cardsType.get(spCardType.getSelectedItemPosition()));
					card.setCurrency(currencies.get(spCardCurrency.getSelectedItemPosition()));

					if (mode == Mode.ADD) {
						CardDAO.create(card);
						KRuntimeModel.getInstance().getCards().add(card);
					} else {
						CardDAO.update(card);
					}
					onBackPressed();
				} catch (SQLException e) {
					showExceptionAsDialog(e);
				} catch (Exception e) {
					showExceptionAsDialog(e);
				}
			}
		});
	}

	private boolean isValidFields() {
		boolean isValid = true;
		if (cnCardNumber.getText().toString().length() == 0) {
			cnCardNumber.setError(ResourceManager.getStringValue(R.string.alert_card_number));
			isValid = false;
		}

		if (etCardCode.getText().toString().length() == 0) {
			etCardCode.setError(ResourceManager.getStringValue(R.string.alert_card_code));
			isValid = false;
		}

		if (cardExpiresEndDate == null) {
			etCardExpiresEnd.setError(ResourceManager.getStringValue(R.string.alert_card_expires));
			isValid = false;
		}
		if (etCardSing.getText().toString().length() == 0) {
			etCardSing.setError(ResourceManager.getStringValue(R.string.alert_card_sing));
			isValid = false;
		}
		if (etCardOwner.getText().toString().length() == 0) {
			etCardOwner.setError(ResourceManager.getStringValue(R.string.alert_card_owner));
			isValid = false;
		}

		return isValid;
	}

	private void editMode(boolean isEditMode) {
		if (!isEditMode) {
			ibCardExpiresEndEdit.setVisibility(View.GONE);
			btAction.setVisibility(View.INVISIBLE);
			cnCardNumber.setEnabled(isEditMode);
			etCardCode.setEnabled(isEditMode);
			etCardExpiresEnd.setEnabled(isEditMode);
			etCardSing.setEnabled(isEditMode);
			spCardType.setEnabled(isEditMode);
			spCardCurrency.setEnabled(isEditMode);
			etCardOwner.setEnabled(isEditMode);
			etCardDescription.setEnabled(isEditMode);
		}
	}

	@Override
	public void onBackPressed() {
		KModel.getInstance().setCard(null);
		KModel.getInstance().setCardMode(null);
		super.onBackPressed();
	}
}